COMP2011 PA1

A Simpified Robot Wars Game Simulation

Responsive image

Super Robot Wars is an engaging series of tactical turn-based video games that captivate players with their unique blend of popular anime storylines, such as Gundam, Mazinger Z, Getter Robo, Neon Genesis Evangelion, and more. The above screenshot serves only as an illustration. In project assignment 1, we have customized rules to simulate key gameplay mechanics.

Introduction

Responsive image

For a complete example, please refer to the side-by-side comparision example below

The simulation commences by retrieving crucial map information, including the number of robots, the map dimensions, the robot names, the robot positions, and the remaining health points. Your primary objective is to accurately simulate the number of actions for some robots, encompassing robot movement, close combat (hit) operations, and ranged combat (shoot) operations. As these actions unfold, the positions and health points of the robots are dynamically updated with suitable success or failure messages. Details will be illustrated in the remaining sections.

Upon completing this project assignment, you will achieve the following learning outcomes:

  • Proficiency in utilizing loops and 1D arrays to manipulate robot information, such as health points
  • Mastery of nested loops and 2D arrays to manipulate the game map
  • Skillful in organizing your program through functions, enhancing its structure and maintainability

Skeleton Code

A skeleton code: pa1_skeleton.zip is provided.
Sample input and output files are included in the zip file.

  • DO NOT start from scratch.
  • You can search the keyword TODO in the skeleton code to locate the parts you need to implement
  • READ the skeleton code carefully. Many useful things are provided in the skeleton code
  • DO NOT include extra header files
  • DO NOT use global variables
  • DO NOT add extra cin or cout statements
    • It is because the input and output handling are given in the skeleton code
    • ZINC is strict when comparing the output text. ZINC can only skip extra empty lines. Extra output statements (e.g., an extra word, an extra sentence, or an extra empty space in the middle) may fail the ZINC test cases
    • If you add extra output statements for debugging purposes, please remember to delete them before your final code submission
  • If needed, you can add extra constants, local variables, and extra helper functions
  • Here is the output of the skeleton code. Your goal is to complete the missing operations.
    The initial game information:
    Robot B HP=99
    Robot C HP=500
    Robot Z HP=1000
    Z . . . . . . . . . 
    . . . . . . . . . . 
    . . . . . . . B . . 
    . . C . . . . . . . 
    . . . . . . . . . . 
    The move action is not implemented yet
    The move action is not implemented yet
    The move action is not implemented yet
    The move action is not implemented yet
    The move action is not implemented yet
    The hit action is not implemented yet
    The hit action is not implemented yet
    The shoot action is not implemented yet
    The shoot action is not implemented yet
    === Game Ended ===

Robot Information

  • To begin, we will gather the necessary robot information from the user
  • The input process commences with entering the total number of robots
  • The valid robot names can be chosen from the range of the capital letter A to Z, inclusive
  • Subsequent lines will record the names of the robots and the corresponding health points
  • For instance, consider the following input as an example, which represents three robots (B, C, and Z):

    3
    B 99
    C 500
    Z 1000

    • Robot B has 99 health points
    • Robot C has 500 health points
    • Robot Z has 1000 health points

Map Information

  • The game map is stored in a 2D character array
  • The following table summarizes characters used in the game map:
    Name Characters Description
    Empty Cell . The . (dot) character represents an empty cell.
    Empty cells cannot be moved.
    Robot A-Z These characters represent robots.
    Robots can be moved.
  • Here is an example game map with 5 rows and 10 columns:

    5 10
    Z.........
    ..........
    .......B..
    ..C.......
    ..........

    In this example, you can see:

    • 3 robots (B, C, and Z) and their positions
    • The remaining cells are empty cells (dot characters)

Robot Operations

  • In this project assignment, you need to simulate 3 types of robot operations:
    • Movement operation
    • Hit operation (i.e., close combat)
    • Shoot operation (i.e., ranged combat)
  • The list of operations is terminated by the exclamation mark (!)
  • For example, the following input consists of 9 operations:

    Z moves east 2
    Z moves north 1
    Z moves south 4
    Z moves south 3
    Z moves south 2
    Z hits south
    Z hits east
    Z shoots north
    Z shoots east
    !

    • 5 of them are movement operations
    • 2 of them are hit operations
    • 2 of them are shoot operations

Operation Type 1: Movement Operations

  • In this project, there are 4 movement directions: east, south, west, north

    robot in 4 possible directions

  • The following sentence format is used to represent a robot movement:
    [Robot Letter] moves [direction word] [number of steps]
    • It starts with a valid robot letter (A-Z)
    • It follows by a keyword "moves"
    • It follows by a valid direction word (east/south/west/north)
    • It follows by a positive integer (i.e., without decimal places) indicating the number of steps.
      • You can assume that the number is always positive (i.e., excluding zero)
      • There won't be an integer overflow issue when adding the number of steps with the current position.
    • Here are some movement examples:
      Sentence Description
      Z moves east 2 Move the robot Z to the east direction by 2 steps.
      B moves north 1 Move the robot B to the north direction by 1 step.
      C moves south 4 Move the robot C to the south direction by 4 steps.
    • There are 3 possible cases:
      • Success. The robot should be moved to the new position.
      • Fail, hitting a boundary. The robot position remains unchanged
      • Here is an example to illustrate the boundary checking:

        Robot blocked by a boundary

      • Fail, there is another robot along the path. The robot position remains unchanged
      • Here is an example to illustrate if there is another robot along the path.

        Robot is blocked by another robot along the path

    • Here are some robot movement examples:

      Movement Before the operation After the operation Reason
      Z moves east 2
      Z . . . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      Success: Robot Z moves along the direction east by 2 step(s)
      Z moves north 1
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      Fail: If robot Z moves along the direction north by 1 step(s), it will move outside a boundary, so the position remains unchanged
      Z moves south 4
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      Fail: If robot Z moves along the direction south by 4 step(s), it will hit another robot along the path, so the position remains unchanged
      Z moves south 3
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      Fail: If robot Z moves along the direction south by 3 step(s), it will hit another robot along the path, so the position remains unchanged
      Z moves south 2
      . . Z . . . . . . .
      . . . . . . . . . .
      . . . . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      . . . . . . . . . .
      . . . . . . . . . .
      . . Z . . . . B . .
      . . C . . . . . . .
      . . . . . . . . . .
      Success: Robot Z moves along the direction south by 2 step(s)

Operation Type 2: Hit Operations

Responsive image
  • If a robot hits another robot, the health point of the target robot will be reduced
  • In the starter code, the following constant is defined for the hit operations:
    // Weapon: for the hit action
    const int WEAPON_HIT_DAMAGE = 200;
    • Using constants is recommended
      • For example, you may change the damage value to another value later
      • You only need to change the corresponding damage value if constant is used properly
      • Otherwise, you may need to change multiple places if the value 200 is used in many places of your code. Your program is wrong if you forget to change some places.
    • The range of the hit operation is 1 step
    • If a robot is being hit, the health point will be reduced by WEAPON_HIT_DAMAGE
    • The target robot will be destroyed if the health point becomes zero
    • If the updated health point is negative, the health point should be set as zero and the robot will be destroyed
  • The following sentence format is used to represent a hit operation:
    [Robot Letter] hits [direction word]
    • It starts with a valid robot letter (A-Z)
    • It follows by a keyword "hits"
    • It follows by a valid direction word (east/south/west/north)
  • In this project, there are 4 hit directions: east, south, west, north

    Hit operation illustration

  • Here are some hit operation examples in our simulation program:

    Movement Current map Result
    Z hits south
    . . . . . . . . . .
    . . . . . . . . . .
    . . Z . . . . B . .
    . . C . . . . . . .
    . . . . . . . . . .
    Success: Robot Z hits C
    Robot C health point is reduced from 500 to 300
    == Health points of alive robots ==
    Robot B HP=99
    Robot C HP=300
    Robot Z HP=1000
    Z hits east
    . . . . . . . . . .
    . . . . . . . . . .
    . . Z . . . . B . .
    . . C . . . . . . .
    . . . . . . . . . .
    Fail: Robot Z cannot hit any target
    == Health points of alive robots ==
    Robot B HP=99
    Robot C HP=300
    Robot Z HP=1000

Operation Type 3: Shoot Operations

Responsive image
  • Same as the hit operation, the health point of the target robot will be reduced if the target robot is being shot by another robot
  • In the starter code, the following constants are defined for the shoot operations
    // Weapon: for the shoot action
    const int WEAPON_SHOOT_DAMAGE = 100;
    const int WEAPON_SHOOT_RANGE = 5;
    • Same as the hit operation, using constants is recommended
    • The range of the shoot operation is WEAPON_SHOOT_RANGE steps
    • If a robot is being shot, the health point will be reduced by WEAPON_SHOOT_DAMAGE
    • The target robot will be destroyed if the health point becomes zero
    • If the updated health point is negative, the health point should be set as zero and the robot will be destroyed
  • The following sentence format is used to represent a hit operation:
    [Robot Letter] shoots [direction word]
    • It starts with a valid robot letter (A-Z)
    • It follows by a keyword "shoots"
    • It follows by a valid direction word (east/south/west/north)
  • In this project, there are 4 shoot directions: east, south, west, north
  • Shoot operations are harder than hit operations. If there are multiple robots along the path in the shoot direction, only the first robot will be shot. For example:

    Shoot operation illustration

  • Here are some shoot operation examples in our simulation program:

    Movement Current map Result
    Z shoots north
    . . . . . . . . . .
    . . . . . . . . . .
    . . Z . . . . B . .
    . . C . . . . . . .
    . . . . . . . . . .
    Fail: Robot Z cannot shoot any target
    == Health points of alive robots ==
    Robot B HP=99
    Robot C HP=300
    Robot Z HP=1000
    Z shoots east
    . . . . . . . . . .
    . . . . . . . . . .
    . . Z . . . . B . .
    . . C . . . . . . .
    . . . . . . . . . .
    Success: Robot Z shoots B
    Robot B health point is reduced from 99 to 0
    Robot B is being destroyed by Z
    . . . . . . . . . .
    . . . . . . . . . .
    . . Z . . . . . . .
    . . C . . . . . . .
    . . . . . . . . . .

A Complete Side-by-Side Comparsion Example

A sample input A sample output
To enhance readability, when lines become excessively long, they are wrapped into multiple lines
3
B 99
C 500
Z 1000
5 10
Z.........
..........
.......B..
..C.......
..........
Z moves east 2
Z moves north 1
Z moves south 4
Z moves south 3
Z moves south 2
Z hits south
Z hits east
Z shoots north
Z shoots east
!
The initial game information:
Robot B HP=99
Robot C HP=500
Robot Z HP=1000
Z . . . . . . . . .
. . . . . . . . . .
. . . . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Success: Robot Z moves along the direction east by 2 step(s)
. . Z . . . . . . .
. . . . . . . . . .
. . . . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Fail: If robot Z moves along the direction north by 1 step(s), it will move outside a boundary, so the position remains unchanged
. . Z . . . . . . .
. . . . . . . . . .
. . . . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Fail: If robot Z moves along the direction south by 4 step(s), it will hit another robot along the path, so the position remains unchanged
. . Z . . . . . . .
. . . . . . . . . .
. . . . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Fail: If robot Z moves along the direction south by 3 step(s), it will hit another robot along the path, so the position remains unchanged
. . Z . . . . . . .
. . . . . . . . . .
. . . . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Success: Robot Z moves along the direction south by 2 step(s)
. . . . . . . . . .
. . . . . . . . . .
. . Z . . . . B . .
. . C . . . . . . .
. . . . . . . . . .
Success: Robot Z hits C
Robot C health point is reduced from 500 to 300
== Health points of alive robots ==
Robot B HP=99
Robot C HP=300
Robot Z HP=1000
Fail: Robot Z cannot hit any target
== Health points of alive robots ==
Robot B HP=99
Robot C HP=300
Robot Z HP=1000
Fail: Robot Z cannot shoot any target
== Health points of alive robots ==
Robot B HP=99
Robot C HP=300
Robot Z HP=1000
Success: Robot Z shoots B
Robot B health point is reduced from 99 to 0
Robot B is being destroyed by Z
. . . . . . . . . .
. . . . . . . . . .
. . Z . . . . . . .
. . C . . . . . . .
. . . . . . . . . .
== Health points of alive robots ==
Robot C HP=300
Robot Z HP=1000
=== Game Ended ===

Assumptions

  • The game map has at least 1 row and at most 20 rows, inclusive
  • The game map has at least 1 column and at most 30 columns, inclusive
  • The game map contains at least 1 robot and at most 26 unique robots (in capital letter A to Z, inclusive)
    • You CAN assume the robot letters are unique. For example, there won't be 2 robots with letter A
    • You CANNOT assume the robot letters are continuous. For example, the map may contains 2 robots B and Y (i.e., robots A, C-X, and Z are missing)
  • There is exactly one ! to indicate the end of the robot operations

Coding Tasks

  • You only need to complete the following coding tasks:

    Task1: Implementing the updateMapForMoveAction function

    // TODO:
    // function updateMapForMoveAction: updates the map and returns the status value after the robot movement
    // @param map: a 2D character array storing the game map
    // @param mapRows: the number of rows of the game map
    // @param mapCols: the number of columns of the game map
    // @param robotLetter: the robot to be moved
    // @param directionLetter: the movement direction
    // @param moveSteps: the number of steps to be moved along the direction
    //
    // @return: the status value, please check the constant values near the top of the starter code.
    // The main function may also help you understand the meanings of the possible return values
    //
    int updateMapForMoveAction(char map[MAX_ROWS][MAX_COLS], const int mapRows, const int mapCols,
                                const char robotLetter, const char directionLetter, const int moveSteps)
    {
        // remove this line to start your work
        return STATUS_ACTION_MOVE_NOT_IMPLMENTED;
    }

    Task2: Implementing the updateHealthPointsForHitAction function

    // TODO:
    // function updateHealthPointsForHitAction: updates the map, healthPoints, and returns the values to the main function after the hit action
    //
    // @param healthPoints: a 1D array storing the healthPoints of robots
    // @param map: a 2D character array storing the game map
    // @param mapRows: the number of rows of the game map
    // @param mapCols: the number of columns of the game map
    // @param robotLetter: the robot to be moved
    // @param directionLetter: the movement direction
    // @param targetRobotLetter: the target robot.
    // @param targetOriginalHealthPoint: the original health point of the target robot.
    // @param targetUpdatedHealthPoint: the updated health point of the target robot.
    //
    //  Note: The pass-by-reference variables will be returned and used in the main function.
    //
    // @return: the status value, please check the constant values near the top of the starter code.
    // The main function may also help you understand the meanings of the possible return values
    int updateHealthPointsForHitAction(int healthPoints[MAX_NUM_ROBOTS],
                                        char map[MAX_ROWS][MAX_COLS],
                                        const int mapRows, const int mapCols,
                                        const char robotLetter,
                                        const char directionLetter,
                                        char &targetRobotLetter,
                                        int &targetOriginalHealthPoint,
                                        int &targetUpdatedHealthPoint)
    {
        // remove this line to start your work
        return STATUS_ACTION_WEAPON_NOT_IMPLEMENTED;
    }

    Task3: Implementing the updateHealthPointsForShootAction function

    // TODO:
    // function updateHealthPointsForShootAction: updates the map, healthPoints, and returns the values to the main function after the shoot action
    //
    // @param healthPoints: a 1D array storing the healthPoints of robots
    // @param map: a 2D character array storing the game map
    // @param mapRows: the number of rows of the game map
    // @param mapCols: the number of columns of the game map
    // @param robotLetter: the robot to be moved
    // @param directionLetter: the movement direction
    // @param targetRobotLetter: the target robot.
    // @param targetOriginalHealthPoint: the original health point of the target robot.
    // @param targetUpdatedHealthPoint: the updated health point of the target robot.
    //
    //  Note: The pass-by-reference variables will be returned and used in the main function.
    //
    // @return: the status value, please check the constant values near the top of the starter code.
    // The main function may also help you understand the meanings of the possible return values
    int updateHealthPointsForShootAction(int healthPoints[MAX_NUM_ROBOTS],
                                         char map[MAX_ROWS][MAX_COLS],
                                         const int mapRows, const int mapCols,
                                         const char robotLetter,
                                         const char directionLetter,
                                         char &targetRobotLetter,
                                         int &targetOriginalHealthPoint,
                                         int &targetUpdatedHealthPoint)
    {
        // remove this line to start your work
        return STATUS_ACTION_WEAPON_NOT_IMPLEMENTED;
    }

Checking uninitialized variables

Many students forget to initialize the variables before using them. Sometimes, it will cause serious problems. In most of the operating systems (e.g., Linux), variables won't be initialized (i.e., there are garbage values stored if the variables are not initialized and being used.)

ZINC is running in Linux, so variables won't be initialized automatically.

The following method can ask the compiler to check uninitialized variables. For example, the following code is stored in a file named uninitialized_variables.cpp, you can add a flag -Wuninitialized to check:

g++ uninitialized_variables.cpp -Wuninitialized

The above technique may be useful for your labs and projects. Here is a demo in vscode:

Responsive image

Compilation and Running Test Cases

Similar to labs, you should follow similar steps to run the test cases. You won't see your ZINC grading report before the deadline.

Limitations of the ZINC system:

  • DO NOT use cerr because ZINC cannot grade cerr output. You can check this problem by following the checking procedures below. In PA1, you CANNOT add extra cin/cout statements, so it won't cause any issues.
  • DO NOT return a non-zero return code in the main function. ZINC will treat your program as "crash" and won't continue the grading. In PA1, you CANNOT modify the main function, so it won't cause any issues.

Please compare your outputs with the desired outputs:

  • In VSCode, please open the terminal by one of the following two ways:
    • Press the key Ctrl+Shift+` in Windows/Linux, or Control+Shift+Backquote in Mac
    • From the menubar, select Terminal > New Terminal
    And then run this code to compile your code:
    g++ -std=c++11 pa1.cpp -o pa1
  • You need to redirect the input of executable program to the txt test case files we provided, and redirect the output to different txt files. Here are the commands:
    • In MacOS or Linux:
      ./pa1 < testcase/input1.txt > myOutput1.txt
    • In Windows:
      Get-Content testcase/input1.txt | ./pa1 > myOutput1.txt

    Please replace the filenames accordingly if you would like to check other output files.

  • After that, you can compare your own output text files with the desired outputs one by one. You can compare any two files by VSCode:
    • Right click the first file you want to compare in VSCode Explorer, choose Select for CompareResponsive image
    • Right click the second file you want to compare in VSCode Explorer, choose Compare with SelectedResponsive image

A Sample Executable in Virtual Barn

Students may use different operating systems (e.g., Windows/Mac/Linux), so the executable file is prepared in Virtual Barn.

If you want to run the sample executable, you should follow How to run pa1.exe? tutorial

Grading

Before the deadline

The following test cases are released:

Sample Input Sample Output Description
input1.txt output1.txt
  • A map with 5 rows and 10 columns
  • 3 robots
  • A good mix of movement, hit, and shoot operations
input2.txt output2.txt
  • A map with 5 rows and 10 columns
  • 1 robot
  • Focusing on successful movements
input3.txt output3.txt
  • A map with 2 rows and 2 columns
  • 4 robots
  • Focusing on failed movements
input4.txt output4.txt
  • A map with 3 rows and 3 columns
  • 5 robots
  • Focusing on successful hit operations
input5.txt output5.txt
  • A map with 3 rows and 3 columns
  • 5 robots
  • Focusing on failed hit operations
input6.txt output6.txt
  • A map with 6 rows and 6 columns
  • 5 robots
  • Focusing on successful shoot operations
input7.txt output7.txt
  • A map with 7 rows and 7 columns
  • 5 robots
  • Focusing on failed shoot operations
input8.txt output8.txt
  • A map with 1 row and 6 columns
  • 3 robots
  • Focusing on multiple robots along the shooting direction

After the deadline

In addition to the given test cases, we have hidden test cases. They are summarized in the following table:

(*): In this project assignment, we may not able to completely isolate one feature from another feature. So, we only list out the main area in the following table.

Main Area (*) Number of
Given Test Cases
Number of
Hidden Test Cases
Total Marks in Each Area
Robot Movement 2 14 16
(1 mark for each case)
Hit Operations 2 8 10
(1 mark for each case)
Shoot Operations 3 11 28
(2 marks for each case)
Mixed Operations 1 2 15
(5 marks for each case)
Total 8 35 MaxTotal = 69
will be normalized to 100
(i.e. YourTotal / MaxTotal * 100)


ZINC will normalize your total score to 100.0 when the grades are released.

Academic Integrity

Important - Academic Integrity at HKUST

We highly value academic integrity. Please read the Honor Code section on our course webpage to make sure you understand what is considered as plagiarism and what the penalties are. The followings are some of the highlights:

  • DO NOT try your "LUCK" - we use sophisticated plagiarism detection software to find cheaters. We also review codes for potential cases manually.
  • The penalty (for BOTH the copier and the copiee) is not just getting a zero in your assignment. Please read the Honor Code thoroughly.
  • Serious offenders will fail the course immediately, and there may be additional disciplinary actions from the department and university, up to and including expulsion.

This programming assignment is challenging, so you are highly recommended to start early. If you need clarification on the requirements, please feel free to post on Piazza. However, to avoid cluttering the forum with repeated/trivial questions, please carefully read the given code, the description, the sample output, and the latest FAQ (refresh this page regularly) in this page before you post your questions. In addition, please be reminded that we won't help debug for any student's assignment for the sake of fairness.

Submission

Deadline: 21-Oct-2023 23:59

You are required to submit your solution to our auto-grading system: ZINC.
Please read the ZINC student submission guidelines if you still don't know how to submit in ZINC.

The filename is pa1.cpp, and submit it to ZINC. 50% penalty will be given if your filename is wrong. You don't need to zip the file if you only submit one file to ZINC.

Filename checking is enabled in ZINC. If your filename is wrong, you should see something like this:

Other names do not work (e.g., PA1.cpp, Pa1.cpp, pa1.cpp.cpp, pa 1.cpp (a space is added between pa and 1) etc. )

Notes:

  • You may submit your file multiple times, but only the last submission will be graded. You do NOT get to choose which version we grade. If you submit after the deadline, late penalty will be applied according to the submission time of your last submission.
  • Submit early to avoid any last-minute problem. Only ZINC submissions will be accepted.
  • The ZINC server will be very busy on the last day especially in the last few hours. However, as long as your submission is successful, we would grade your latest submission with all test cases after the deadline.
  • Make sure you submit the correct file yourself. You can download your own file back from ZINC to verify. Again, we only grade what you uploaded last to ZINC.

Compilation Requirements

Make sure your program can be compiled and be able to execute.

If we cannot even compile your work, it won't be graded. Therefore, for parts that you cannot finish, just put in dummy/empty implementation so that your whole program can be compiled for ZINC to grade the other parts that you have done.

Late Submission Policy

There will be a penalty of -1 point (out of a maximum 100 points) for every minute you are late.
In other words, if you are late for more than 100 minutes, you will get 0 marks.

FAQs

This section will be updated after the release

My code doesn't work / there is an error, here is the code, can you help me fix it?

As the assignment is a major course assessment, to be fair, we should not finish the tasks for you.
We might provide you some hints, but we won't debug for you.